/**************************************************************************//**
 * @file     hal_stm32f1xx_flash_api.h
 * @brief    stm32f1xx FLASH模块对外提供的公共接口
 * @version  V0.0.1
 * @date     2020-02-01
 ******************************************************************************/
/*
 * Copyright (c) 2020, 2020 by xiao xiang. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * is freely granted, provided that this notice is preserved.
 */

#ifndef _HAL_STM32F1XX_FLASH_API_H_
#define _HAL_STM32F1XX_FLASH_API_H_

#include "common.h"
#include "hal_stm32f1xx_reg_base_api.h"

/** 
  * @brief Bit definition for FLASH_ACR register，复位值： 0x0000 0030
  */
typedef union {
    struct {
        uint32_t LATENCY : 3; /*!< 时延，SYSCLK(系统时钟)周期与闪存访问时间的比例 */
        uint32_t HLFCYA  : 1; /*!< 闪存半周期访问 0=禁止半周期访问 1=使能半周期访问 */
        uint32_t PRFTBE  : 1; /*!< 预取缓冲区控制 0=关闭预取 1=打开预取 */
        uint32_t PRFTBS  : 1; /*!< 预取缓冲区状态指示 0=预取关闭 1=预取打开 */
        uint32_t rsv1    : 26;
    };
    uint32_t reg;
} UN_FLASH_ACR;

#define FLASH_ACR_LATENCY_0   0 /*!< 000：零等待状态，当 0 < SYSCLK ≤ 24MHz */
#define FLASH_ACR_LATENCY_1   1 /*!< 001：一个等待状态，当 24MHz < SYSCLK ≤ 48MHz */
#define FLASH_ACR_LATENCY_2   2 /*!< 010：两个等待状态，当 48MHz < SYSCLK ≤ 72MHz */

/** 
  * @brief Bit definition for FLASH_KEYR register
  */
typedef union {
    struct {
        uint32_t FKEYR;   /*!< 用于输入FPEC的解锁键 */
    };
    uint32_t reg;
} UN_FLASH_KEYR;

/** 
  * @brief Bit definition for FLASH_OPTKEYR register
  */
typedef union {
    struct {
        uint32_t OPTKEYR;   /*!< 用于输入选项字节的键以解除OPTWRE */
    };
    uint32_t reg;
} UN_FLASH_OPTKEYR;

/** 
  * @brief Bit definition for FLASH_SR register，闪存状态寄存器 复位值： 0x0000 0000
  */
typedef union {
    struct {
        uint32_t BSY      : 1;  /*!< 忙指示状态 */
        uint32_t RSV1     : 1;
        uint32_t PGERR    : 1;  /*!< 编程错误，试图对内容不是’0xFFFF’的地址编程时，硬件设置这位为’1’ */
        uint32_t RSV2     : 1;
        uint32_t WRPRTERR : 1;  /*!< 写保护错误 */
        uint32_t EOP      : 1;  /*!< 操作状态，当闪存操作(编程/擦除)完成时，硬件设置这位为’1’ */
        uint32_t RSV3     : 26;
    };
    uint32_t reg;
} UN_FLASH_SR;

/** 
  * @brief Bit definition for FLASH_CR register 闪存控制寄存器 复位值： 0x0000 0080
  */
typedef union {
    struct {
        uint32_t PG     : 1;  /*!< 选择编程操作。 */
        uint32_t PER    : 1;  /*!< 页擦除 */
        uint32_t MER    : 1;  /*!< 全擦除，选择擦除所有用户页。 */
        uint32_t RSV1   : 1;
        uint32_t OPTPG  : 1;  /*!< 烧写选项字节 */
        uint32_t OPTER  : 1;  /*!< 擦除选项字节 */
        uint32_t STRT   : 1;  /*!< 当该位为’1’时将触发一次擦除操作。 */
        uint32_t LOCK   : 1;  /*!< 锁状态，只能写1，由硬件清零 */
        uint32_t RSV2   : 1;
        uint32_t OPTWRE : 1;  /*!< 允许写选项字节,当该位为’1’时，允许对选项字节进行编程操作。 */
        uint32_t ERRIE  : 1;  /*!< 允许错误状态中断 */
        uint32_t RSV3   : 1;
        uint32_t EOPIE  : 1;  /*!< 允许操作完成中断 */
        uint32_t RSV4   : 19;
    };
    uint32_t reg;
} UN_FLASH_CR;

/** 
  * @brief Bit definition for FLASH_AR register 闪存地址寄存器 复位值： 0x0000 0000
  */
typedef union {
    struct {
        uint32_t FAR; /*!< 闪存地址，当进行编程时选择要编程的地址，当进行页擦除时选择要擦除的页。 */
    };
    uint32_t reg;
} UN_FLASH_AR;

/** 
  * @brief Bit definition for FLASH_OBR register 选项字节寄存器 复位值： 0x03FF FFFC
  */
typedef union {
    struct {
        uint32_t OPTERR     : 1;  /*!< 选项字节错误，当该位为’1’时表示选项字节和它的反码不匹配。 */
        uint32_t RDPRT      : 1;  /*!< 读保护，当设置为1，表示闪存存储器被写保护。 */
        uint32_t WDG_SW     : 1;
        uint32_t nRST_STOP  : 1;
        uint32_t nRST_STDBY : 1;
        uint32_t RSV1       : 5;
        uint32_t Data2      : 8;
        uint32_t Data1      : 8;
        uint32_t RSV2       : 6;
    };
    uint32_t reg;
} UN_FLASH_OBR;

/** 
  * @brief Bit definition for FLASH_WRPR register 写保护寄存器 复位值： 0xFFFF FFFF
  */
typedef union {
    struct {
        uint32_t WRP;   /*!< 写保护，0=写保护生效 1=写保护失效 */
    };
    uint32_t reg;
} UN_FLASH_WRPR;

/** 
  * @brief FLASH Registers
  */
typedef struct {
  // 闪存访问控制寄存器
  __IO UN_FLASH_ACR ACR;

  // 下面几个寄存器属于闪存编程和擦除控制器（FPEC）寄存器
  __IO UN_FLASH_KEYR KEYR;
  __IO UN_FLASH_OPTKEYR OPTKEYR;
  __IO UN_FLASH_SR SR;
  __IO UN_FLASH_CR CR;
  __IO UN_FLASH_AR AR;
  __IO uint32_t RESERVED;
  __IO UN_FLASH_OBR OBR;
  __IO UN_FLASH_WRPR WRPR;
} FLASH_TypeDef;

#define FLASH   ((FLASH_TypeDef *)FLASH_R_BASE)

#define FLASH_ACR_PREFETCH_DISABLE  0x0 /*!< 关闭 Flash预取 */
#define FLASH_ACR_PREFETCH_ENABLE   0x1 /*!< 打开 Flash预取 */

/**
  * @brief  Enable the FLASH prefetch buffer. 使能Flash预取功能，提升性能
  * @retval None
  */ 
#define HAL_FLASH_PREFETCH_BUFFER_ENABLE()  (FLASH->ACR.PRFTBE = FLASH_ACR_PREFETCH_ENABLE)

#endif